package com.blue.Impl.author;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blue.common.constant.CommonConstant;
import com.blue.common.entity.ResponseResult;
import com.blue.common.exception.CustomException;
import com.blue.common.utils.AESUtils;
import com.blue.common.utils.ConvertUtils;
import com.blue.common.utils.RedisUtils;
import com.blue.dto.author.UserDTO;
import com.blue.mapper.author.UserMapper;
import com.blue.po.author.UserPO;
import com.blue.po.author.UserPostPO;
import com.blue.po.author.UserRolePO;
import com.blue.service.author.IUserPostService;
import com.blue.service.author.IUserRoleService;
import com.blue.service.author.IUserService;
import com.blue.vo.author.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserPO> implements IUserService {

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IUserPostService userPostService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    @Transactional
    public void add(UserDTO requestDTO) throws Exception {
        List<UserPO> userPOS = this.list(new LambdaQueryWrapper<UserPO>()
                .eq(UserPO::getUserNo, requestDTO.getUserNo()));
        if (CollectionUtil.isNotEmpty(userPOS)) {
            throw new CustomException("该账号系统已存在，请重新输入");
        }
        String password = AESUtils.encrypt(requestDTO.getPassword());
        requestDTO.setPassword(password);
        UserPO userPO = ConvertUtils.convert(UserPO.class, requestDTO);
        this.save(userPO);
        saveRelationData(userPO, requestDTO);
    }

    @Override
    @Transactional
    public void edit(UserDTO requestDTO) {
        UserPO userPO = ConvertUtils.convert(UserPO.class, requestDTO);
        this.updateById(userPO);
        userRoleService.remove(new LambdaQueryWrapper<UserRolePO>()
                .eq(UserRolePO::getUserId, userPO.getUserId()));
        userPostService.remove(new LambdaQueryWrapper<UserPostPO>()
                .eq(UserPostPO::getUserId, userPO.getUserId()));
        saveRelationData(userPO, requestDTO);
    }

    private void saveRelationData(UserPO userPO, UserDTO requestDTO) {
        List<String> roleIds = requestDTO.getRoleIds();
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<UserRolePO> userRolePOS = new ArrayList<>();
            roleIds.forEach(item -> {
                UserRolePO userRolePO = new UserRolePO();
                userRolePO.setRoleId(item);
                userRolePO.setUserId(userPO.getUserId());
                userRolePOS.add(userRolePO);
            });
            userRoleService.saveBatch(userRolePOS);
        }
        List<String> postIds = requestDTO.getPostIds();
        if (!CollectionUtils.isEmpty(postIds)) {
            List<UserPostPO> userRolePOS = new ArrayList<>();
            postIds.forEach(item -> {
                UserPostPO userPostPO = new UserPostPO();
                userPostPO.setPostId(item);
                userPostPO.setUserId(userPO.getUserId());
                userRolePOS.add(userPostPO);
            });
            userPostService.saveBatch(userRolePOS);
        }
    }

    @Transactional
    @Override
    public void delete(List<String> ids) {
        //删除用户角色关系数据
        userRoleService.remove(new LambdaQueryWrapper<UserRolePO>()
                .in(UserRolePO::getUserId, ids));
        userPostService.remove(new LambdaQueryWrapper<UserPostPO>()
                .in(UserPostPO::getUserId, ids));
        //删除用户数据
        this.removeByIds(ids);
    }

    @Override
    public UserVO queryById(String userId) {
        UserPO userPO = this.getById(userId);
        UserVO userVO = ConvertUtils.convert(UserVO.class, userPO);
        List<UserRolePO> userRolePOS = userRoleService.list(new LambdaQueryWrapper<UserRolePO>()
                .select(UserRolePO::getRoleId)
                .eq(UserRolePO::getUserId, userId));
        List<String> roleIds = userRolePOS.stream().map(UserRolePO::getRoleId).toList();
        userVO.setRoleIds(roleIds);
        List<UserPostPO> userPostPOS = userPostService.list(new LambdaQueryWrapper<UserPostPO>()
                .select(UserPostPO::getPostId)
                .eq(UserPostPO::getUserId, userId));
        List<String> postIds = userPostPOS.stream().map(UserPostPO::getPostId).toList();
        userVO.setPostIds(postIds);
        return userVO;
    }

    @Override
    public void offline(String userId) {
        redisUtils.cacheValue("offline_key:" + userId, CommonConstant.YES);
    }
}
